package com.sf.dlb.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.concurrent.TimeUnit;

/**
 * cmd调用python工具类
 */
public class PyCaller {
    private static Logger logger = LoggerFactory.getLogger(PyCaller.class);

    public static final String exec_command= "C:\\Python\\Python37-32\\python";
    //export PYSPARK_PYTHON=/usr/bin/python
//    public static final String py_url = "D:\\testCode\\test.py";
    public static final String py_url = "D:\\testCode\\newsreader_dlb_script.py";
    public static final String py_url_parameter_address = "0xb0d92cdadf4a57f5fdb1016d970426960c4a0cc0";
    public static final String py_url_parameter_dlb = "1";
    public static final String py_python_output = "D:\\testCode\\temp.txt";
    public static final String py_python_charsetname = "GBK";

    /**
     * 命令执行
     * @param cmd 要执行的命令
     * @param envs 要设置的环境变量
     * @param timeout 超时时间(秒)
     * @return
     */
    public static String execCMD(String cmd, String[] envs, int timeout) {
        Process process = null;
        StringBuilder sbStd = new StringBuilder(); //正常sb
        StringBuilder sbErr = new StringBuilder(); //错误sb

        long start = System.currentTimeMillis() / 1000; //cmd执行开始时间
        try {
            //执行命令
            if (envs == null) {
                process = Runtime.getRuntime().exec(cmd); //执行命令
            } else {
                process = Runtime.getRuntime().exec(new String[] { "/bin/sh", "-c", cmd }, envs); //执行复杂的命令；envs=设置环境变量
            }
            //cmd流
            BufferedReader brStd = new BufferedReader(new InputStreamReader(process.getInputStream(), py_python_charsetname));//cmd正常输入流
            BufferedReader brErr = new BufferedReader(new InputStreamReader(process.getErrorStream(), py_python_charsetname));//cmd错误输入流
            String line = null;
            //循环从输入流读取数据
            while (true) {
                //从正常输入流读取数据，如果一直有数据，就一直读取；
                if (brStd.ready()) {
                    line = brStd.readLine();
                    sbStd.append(line + "\n");
                    continue;
                }
                //从错误输入流读取数据，如果一直有数据，就一直读取；
                if (brErr.ready()) {
                    line = brErr.readLine();
                    sbErr.append(line + "\n");
                    continue;
                }
                //判断子进程是否正常退出；
                if (process != null) {
                    try {
                        //如果正常退出，就直接break退出循环，否则抛出异常
                        process.exitValue();
                        break;
                    } catch (IllegalThreadStateException e) {
                        logger.info("IllegalThreadStateException is errer");
                    }
                }
                //判断cmd执行时间是否超时了，超时了就break退出循环
                if (System.currentTimeMillis() / 1000 - start > timeout) {
                    sbErr.append("\n命令执行超时退出.");
                    break;
                }
                try {
                    //如果以上都不成立，睡眠500毫秒
                    TimeUnit.MILLISECONDS.sleep(500);
                } catch (InterruptedException e) {
                    logger.info("InterruptedException is errer");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //释放process
            if (process != null) {
                process.destroy();
            }
        }
        //返回输出流的信息；
        if (sbErr.length()>0) {
            return sbErr.toString();
        } else {
            return sbStd.toString();
        }
    }

    /**
     * 执行cmd命令
     * @return
     */
    public static String execPy(String cmd) {
        Process proc = null;
        try {
            System.out.println("cmd="+cmd);
            proc = Runtime.getRuntime().exec(cmd);
            InputStream inputStream=proc.getInputStream();
            BufferedReader rb=new BufferedReader(new InputStreamReader(inputStream));
            String line="";
            StringBuffer stringBuffer=new StringBuffer();
            while ((line=rb.readLine())!=null){
                stringBuffer.append(line).append("\n");
            }
            proc.waitFor();
            inputStream.close();
            rb.close();
            proc.destroy();
            return stringBuffer.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 读取文件
     * @return
     */
    public static String readAnswer() {
        BufferedReader br;
        String answer = null;
        try {
            br = new BufferedReader(new FileReader(new File(py_python_output)));
            answer = br.readLine();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return answer;
    }

    // 测试码
    public static void main(String[] args) throws IOException, InterruptedException {
        StringBuffer cmd=new StringBuffer();
        cmd.append(exec_command)
                .append(" ").append(py_url)
                .append(" ").append(py_url_parameter_address)
                .append(" ").append(py_url_parameter_dlb);
        //写文件的方式
        execPy(cmd.toString());
        String fileResult=readAnswer();
        System.out.println("PyCaller === "+fileResult);
        //读取输出日志的方式，可以设置超时时间
//        String resultStr=execCMD(cmd.toString(),null,20);
//        System.out.println("PyCaller === "+resultStr);
    }
}